﻿#include "cimpques.h"
#include "cquestion.h"
#include "mainwindow.h"
#include "mainwindow.h"
#include "ui_cimpques.h"

#include <QFileDialog>
#include <QDebug>
#include <QCryptographicHash>

#include <sql/csqlmanager.h>
#include "csetting.h"

QStringList g_protectionPositions = {"Java", "Native", "Java+Native"};
QStringList g_difficulty = {"A", "B", "C", "D"};

CImpQues::CImpQues(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::CImpQues)
{
    ui->setupUi(this);

    init();
}

CImpQues::~CImpQues()
{
    delete ui;
}

/**
 * @brief 界面初始化
 */
void CImpQues::init()
{
    // 窗口名称
    setWindowTitle(WINDOW_TITLE_IMPORT_QUES);

    // 防护位置
    ui->cbx_defence->addItems(g_protectionPositions);
    // 难度
    ui->cbx_defficuty->addItems(g_difficulty);
}

/**
 * @brief 选择新的题目所在的路径
 */
void CImpQues::on_btn_view_clicked()
{
    QString qstr_dir = QFileDialog::getExistingDirectory(this, QString::fromLocal8Bit("选择新题所在目录"),  QString::fromLocal8Bit(""), NULL);

    if (qstr_dir.isNull())
    {
        // 用户点击了取消
#ifdef _N_Debug_
        qDebug() << "CImpQues::on_btn_view_clicked() >> 用户点击了取消";
#endif
    }
    else
        // 选择了一个目录
    {
        // 路径显示到界面上
        ui->edt_dir->setText(qstr_dir);
        // 获取文件夹下所有文件名
        QStringList files = getFilesNameWithDir(qstr_dir);
#ifdef _N_Debug_
        for(QString filename : files)
        {
            qDebug() << "文件夹中有文件：" << filename;
        }
#endif
        ui->cbx_mainfile->addItems(files);
    }
}

/**
 * 记录插入到数据库中
 * 文件复制到题库设置的目录
 */
void CImpQues::addQuestion()
{
#ifdef _N_Debug_
    qDebug() << "导入新题窗口下的【OK】按钮被点击了。";
#endif
    // 1. 获取所有的一个输入
    // 1.1 题目所在目录
    QString qstr_dir = ui->edt_dir->text();
    // 1.2 题目主文件
    QString qstr_mainFile = ui->cbx_mainfile->currentText();
    // 1.3 防护位置
    QString qstr_protect = ui->cbx_defence->currentText();
    // 1.4 难度
    QString qstr_difficulty = ui->cbx_defficuty->currentText();
    // 1.5 flag
    QString qstr_flag = ui->edt_flag->text();
    // 1.6 考点
    QString qstr_knowledgePoints = ui->edt_point->text();
    // 1.7 来源
    QString qstr_quesFrom = ui->edt_quesFrom->text();

    // 2. 获取当前选择的难度的已有题目数量
    // 题目编号
    QString qstr_innerNumber;
    // 获取满足条件的总的记录数，不要返回数据
    int size = CQuestion::queryQuestionsTable(nullptr, 0, QUES_DIFFICULTY, "difficulty = '" + qstr_difficulty + "'", false);
#ifdef _N_Debug_
    qDebug() << "CImpQues::on_btn_impQues_clicked() 难度为" << qstr_difficulty << "的数量有： " << size;
#endif
    qstr_innerNumber = QString::number(++size);

    // 文件md5
    QString qstr_mainFilePath = qstr_dir + "/" + qstr_mainFile;
    QFile theFile(qstr_mainFilePath);
    theFile.open(QIODevice::ReadOnly);
    QByteArray bytesOfMd5 = QCryptographicHash::hash(theFile.readAll(), QCryptographicHash::Md5);
    theFile.close();
    QString qstr_fileMd5 = bytesOfMd5.toHex().constData();

    // 校验文件md5是否已经存在
    bool isExist = CQuestion::isExistQuestion(QUES_FILEMD5, QUES_FILEMD5 + "='"+qstr_fileMd5+"'");
    if (isExist == true)
    {
        emit(MainWindow::sp_mainWindows->printRunningLog("题目[" + qstr_fileMd5 + "]已经存在。"));
        return;
    }
    qDebug() << "CImpQues::isExist()：" << isExist;
#ifdef _N_Debug_
        qDebug() << "CImpQues::on_btn_impQues_clicked() 主文件路径：" << qstr_mainFilePath << " Md5： " << qstr_fileMd5;
#endif

    // 数据增加到数据库中
    //stQuestion ques = {qstr_protect, qstr_difficulty, qstr_innerNumber, qstr_fileMd5, qstr_flag, qstr_knowledgePoints, qstr_quesFrom};
    QString doubleQuotationMark = "\"";
    QString sql = "insert into " + QString(QUES_TABLE_NAME) + " values(";
    sql += doubleQuotationMark + qstr_protect + doubleQuotationMark + ", ";
    sql += doubleQuotationMark + qstr_difficulty         + doubleQuotationMark + ", ";
    sql += doubleQuotationMark + qstr_innerNumber        + doubleQuotationMark + ", ";
    sql += doubleQuotationMark + qstr_fileMd5            + doubleQuotationMark + ", ";
    sql += doubleQuotationMark + qstr_flag               + doubleQuotationMark + ", ";
    sql += doubleQuotationMark + qstr_knowledgePoints    + doubleQuotationMark + ", ";
    sql += doubleQuotationMark + qstr_quesFrom           + doubleQuotationMark;
    sql += ")";

    QSqlDatabase db = QSqlDatabase::database("qt_sql_default_connection");
    bool exeResult = CSQLManager::exec(db, sql);
    db.close();
    if(!exeResult)
    {
#ifdef _N_Debug_
        qDebug() << "CImpQues::on_btn_impQues_clicked() 执行sql语句失败。sql语句为：" << sql;
#endif
        return;
    }
    else
    {
        // 复制文件到目标文件夹
        QString dstDir = CSetting::getSettingInstance().dir_baseQuesLib + "/" + qstr_difficulty + "/" + qstr_innerNumber;
#ifdef _N_Debug_
        qDebug() << "复制文件夹源：" << qstr_dir << " 目标：" << dstDir;
#endif
        QDir newDir(dstDir);
        if (!newDir.exists())
        {
            newDir.mkdir(dstDir);
        }
        if ( copyFiles_Folder2Folder(qstr_dir, dstDir))
        {
#ifdef _N_Debug_
        qDebug() << "CImpQues::on_btn_impQues_clicked() 复制文件夹成功。";
#endif
            // 将和主文件名相同的文件，用md5值进行重命名
            QString mainFileName_noDot = qstr_mainFile.mid(0, qstr_mainFile.lastIndexOf('.'));
            QStringList files = getFilesNameWithDir(dstDir);
            for(QString filename : files)
            {
                int index = filename.lastIndexOf('.');
                QString fileName_noDot = filename.mid(0, index);
                QString lastDot = filename.mid(index);
                if (fileName_noDot == mainFileName_noDot)
                {
                    QFile file(dstDir + "/" + filename);
#ifdef _N_Debug_
                    bool ok = file.rename(dstDir + "/" + qstr_fileMd5+lastDot);
                    qDebug() << L8BStr("【CImpQues::on_btn_impQues_clicked()】要修改文件名的文件为：") << filename;
                    qDebug() << L8BStr("【CImpQues::on_btn_impQues_clicked()】修改结果为：") << ok;
#else
                    file.rename(dstDir + "/" + qstr_fileMd5+lastDot);
#endif
                }
            }
        }
        else
        {
#ifdef _N_Debug_
        qDebug() << "[error]CImpQues::on_btn_impQues_clicked() 复制文件夹失败。";
#endif
        }
    }

}

void CImpQues::on_btn_impQues_accepted()
{
    addQuestion();
}
